﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms.DataVisualization.Charting;
using System.Timers;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using DataSimDLL;

namespace BDSim
{
    /// <summary>
    /// UserMonitorView.xaml 的交互逻辑
    /// </summary>
    public partial class ReceiverMonitorView : UserControl, INotifyPropertyChanged
    {
        public ReceiverMonitorView()
        {
            InitializeComponent();
        }

        #region//属性、成员
        bool _IsUpdatePos = true;

        public bool IsUpdatePos
        {
            get { return _IsUpdatePos; }
            set { _IsUpdatePos = value; }
        }

        ObservableCollection<IPPositionEvaluation> _PPositionEvaluationList = new ObservableCollection<IPPositionEvaluation>();

        public ObservableCollection<IPPositionEvaluation> PPositionEvaluationList
        {
            get { return _PPositionEvaluationList; }
            set { _PPositionEvaluationList = value; NotifyPropertyChanged("ReceiverModelList"); }
        }

        IPPositionEvaluation _currentEvaluationModel;

        public IPPositionEvaluation CurrentEvaluationModel
        {
            get { return _currentEvaluationModel; }
            set {
                if (value != null)
                {
                    ChangeMonitorObject(value);
                }
                 _currentEvaluationModel = value; }
        }

        Timer Timer = new Timer(2000);

        /// <summary>
        /// 星空参数列表
        /// </summary>
        //List<SatSpaceUC.SatPredictStatus> SatSpaceParamList = new List<SatSpaceUC.SatPredictStatus>();
        string chk_imagePath = string.Format("{0}\\Resources\\Images\\chk_checked.png", Directory.GetCurrentDirectory());//取得选择图片的绝对路径

        string unchk_imagePath = string.Format("{0}\\Resources\\Images\\chk_unchecked.png", Directory.GetCurrentDirectory());//取得未选择图片的绝对路径

        DopEnum _dopType = DopEnum.GDOP;
        DopEnum PreDopType = DopEnum.GDOP;

        public DopEnum DopType
        {
            get { return _dopType; }
            set {
                if (chart1.Titles.Count>0)
                {
                    chart1.Titles[0].Text = chart1.Titles[0].Text.Replace(_dopType.ToString(), value.ToString());
                }
                _dopType = value; }
        }

        List<DopEnum> _dopList = new List<DopEnum>() { { DopEnum.GDOP }, { DopEnum.PDOP }, {DopEnum.HDOP},{DopEnum.VDOP},{ DopEnum.TDOP } };

        public List<DopEnum> DopList
        {
            get { return _dopList; }
            set { _dopList = value; }
        }
        #endregion

        #region///更换监控对象
        /// <summary>
        /// 更换监控对象
        /// </summary>
        /// <param name="newMonitorObject">新的监控对象</param>
        void ChangeMonitorObject(IPPositionEvaluation newMonitorObject)
        {
            if (_currentEvaluationModel != null)
            {
                _currentEvaluationModel.UpDatePPositionResult = null;
                chart1.Series[0].Points.Clear();
                chart2.Series[0].Points.Clear();
                chart2.Series[1].Points.Clear();
                chart2.Series[2].Points.Clear();
                ChangeName(newMonitorObject.ToString());
            }
            newMonitorObject.UpDatePPositionResult = DataUpdate;
        }

        /// <summary>
        /// 修改表头的名称
        /// </summary>
        /// <param name="newName"></param>
        void ChangeName(string newName)
        {
            //satSpaceUCView.SetName(newName);
            chart1.Titles[0].Text = chart1.Titles[0].Text.Replace(_currentEvaluationModel.ToString(), newName);
            chart2.Titles[0].Text = chart2.Titles[0].Text.Replace(_currentEvaluationModel.ToString(), newName);
        }
        #endregion

        #region///初始化
        public void Init()
        {
            PPositionEvaluationList.Clear();
            //把用户段所有接收机添加到接收机列表
            foreach (var item in ((DataContext as MainWindowViewModel).Scenario.SegmentColletion[3] as UserSegment).UserModelList)
            {
                foreach (var receiver in item.RecCollection)
                {
                    PPositionEvaluationList.Add(receiver);
                }
            }
            foreach (var subGround in ((DataContext as MainWindowViewModel).Scenario.SegmentColletion[2] as GroundSegment).SubGroundSegmentList)
            {
                foreach (var stationList in subGround.GroundList)
                {
                    if (stationList.Type == EStationType.MonitorStation)
                    {
                        foreach (var monitor in stationList.StationList)
                        {
                            PPositionEvaluationList.Add(((MonitorStation)monitor).MonitorReceivers[0]);
                        }
                    }
                }
            }
            if (PPositionEvaluationList.Count > 0)
            {
                InitCharts(PPositionEvaluationList[0].ToString());
                cbxReceiver.SelectedIndex = 0;
            }
        }
        #endregion

        #region 实测数据定位初始化
        public void OriginDataPPositionInit()
        {
            if (PPositionEvaluationList.Count > 0)
            {
                InitCharts(PPositionEvaluationList[0].ToString());
                cbxReceiver.SelectedIndex = 0;
            }
        }
        #endregion

        #region 接收机数据更新方法
        /// <summary>
        /// 数据更新方法
        /// </summary>
        /// <param name="xyzError"></param>
        /// <param name="UserPPosBLH"></param>
        /// <param name="time"></param>
        /// <param name="spaceList"></param>
        public void DataUpdate(NodePosVel xyzError, NodePosVel xyz, UTCTime time, List<SatPredictStatus> spaceList, DopDLL.DopOutput dop)
        {
            if (PreDopType!=DopType)
            {
                PreDopType = DopType;
                chart1.Series[0].Points.Clear();
            }

            if (IsUpdatePos)
            {
                switch (DopType)
                {
                    case DopEnum.GDOP:
                        chart1.Series[0].Points.AddY(dop.GDOP);
                        break;
                    case DopEnum.PDOP:
                        chart1.Series[0].Points.AddY(dop.PDOP);
                        break;
                    case DopEnum.HDOP:
                        chart1.Series[0].Points.AddY(dop.HDOP);
                        break;
                    case DopEnum.VDOP:
                        chart1.Series[0].Points.AddY(dop.VDOP);
                        break;
                    case DopEnum.TDOP:
                        chart1.Series[0].Points.AddY(dop.TDOP);
                        break;
                    default:
                        break;
                }
                NodePosVel ppXYZ = xyz;
                xTextBlock.Text = ppXYZ.X.ToString();
                yTextBlock.Text = ppXYZ.Y.ToString();
                zTextBlock.Text = ppXYZ.Z.ToString();
                BLH_PosVel ppBLH;
                TimeSpaceDll.XYZ2BLH(ppXYZ, ECFtype.type_CGCS2000, out ppBLH);
                bTextBlock.Text = ppBLH.B.ToString();
                lTextBlock.Text = ppBLH.L.ToString();
                hTextBlock.Text = ppBLH.H.ToString();

                //chart2.Series[0].Points.AddXY(time.ToDateTime(), UserPPosBLH.B);
                //chart2.Series[1].Points.AddXY(time.ToDateTime(), UserPPosBLH.L);
                //chart2.Series[2].Points.AddXY(time.ToDateTime(), UserPPosBLH.H);
                chart2.Series[0].Points.AddY(xyzError.X);
                chart2.Series[1].Points.AddY(xyzError.Y);
                chart2.Series[2].Points.AddY(xyzError.Z);
                satSpaceUCView.ClearPaint();
                if (spaceList.Count != 0)
                {
                    foreach (var spaceData in spaceList)
                    {
                        switch (spaceData.SatType)
                        {
                            case EConstellationType.BD:
                                satSpaceUCView.BD2SatStatusList.Add(spaceData);
                                break;
                            case EConstellationType.GPS:
                                satSpaceUCView.GPSSatStatusList.Add(spaceData);
                                break;
                            case EConstellationType.GLONASS:
                                satSpaceUCView.GLOSatStatusList.Add(spaceData);
                                break;
                            case EConstellationType.GALILEO:
                                satSpaceUCView.GALSatStatusList.Add(spaceData);
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
            //UserPosBufferData newData = new UserPosBufferData() { UserPos = UserPPosBLH, Time = time };
            //bufferPosData.Enqueue(newData);
            //if (AddDataThread.ThreadState == (ThreadState)(68))
            //{
            //    AddDataThread.Resume();
            //}
        }
        #endregion

        #region 添加数据到图表
        /// <summary>
        /// 把数据添加到图表中
        /// </summary>
        //void AddDataToChart()
        //{
        //    while (IsUpdatePos)
        //    {
        //        if (bufferPosData.Count() <= 0)
        //        {
        //            //AddDataThread.Suspend();
        //        }
        //        else
        //        {
        //            UserPosBufferData newData = bufferPosData.Dequeue();
        //            this.Dispatcher.BeginInvoke(new DispatcherDelegate(()=>
        //            {
        //                chart1.Series[0].Points.AddXY(newData.UserPos.B, newData.UserPos.L);

        //                chart2.Series[0].Points.AddXY(newData.Time.ToDateTime(), newData.UserPos.B);
        //                chart2.Series[1].Points.AddXY(newData.Time.ToDateTime(), newData.UserPos.L);
        //                chart2.Series[2].Points.AddXY(newData.Time.ToDateTime(), newData.UserPos.H);
        //            }));
        //        }
        //    }
        //}
        #endregion

        #region 界面逻辑
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;

            //chart2.ChartAreas[0].AxisX.Interval = 1;
            //chart2.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Hours;
            //chart2.ChartAreas[0].AxisX.LabelStyle.Format = "G";
            chart2.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
            //AddDataThread.Start();
        }
        #endregion

        #region 初始化图表状态
        /// <summary>
        /// 初始化图表状态
        /// </summary>
        /// <param name="chartType"></param>
        /// <param name="userName"></param>
        public void InitCharts(string userName)
        {
            satSpaceUCView.ClearPaint();
            chart1.Series.Clear();
            chart2.Series.Clear();
            chart1.Titles.Clear();
            chart2.Titles.Clear();
            chart1.Legends.Clear();
            chart2.Legends.Clear();
            
                    Series userTrack = new Series("精度因子") { ChartType = SeriesChartType.FastLine, BorderWidth = 1, Color = System.Drawing.Color.Red };
                    chart1.Series.Add(userTrack);
                    //SetSimpleLegend(chart1);
                    chart1.Titles.Add("<" + userName + ">定位精度因子:" + DopType.ToString());

                    Series userB = new Series("X方向误差(m)") { ChartType = SeriesChartType.FastLine, BorderWidth = 1, Color = System.Drawing.Color.Red };
                    Series userL = new Series("Y方向误差(m)") { ChartType = SeriesChartType.FastLine, BorderWidth = 1, Color = System.Drawing.Color.Blue };
                    Series userH = new Series("Z方向误差(m)") { ChartType = SeriesChartType.FastLine, BorderWidth = 1, Color = System.Drawing.Color.Green };
                    chart2.Series.Add(userB);
                    chart2.Series.Add(userL);
                    chart2.Series.Add(userH);
                    chart2.ChartAreas[0].AxisX.Title = "仿真步数";
                    chart2.ChartAreas[0].AxisY.Title = "当前值(m)";
                    SetCustomLegend(chart2);
                    chart2.Titles.Add("<" + userName + ">定位评估：CGCS2000");

                    //chart2.AxisViewChanged += new EventHandler<ViewEventArgs>(AxisViewChangedEvent);
                    //chart2.SelectionRangeChanged += new EventHandler<CursorEventArgs>(SelectionChangedEvent);
                
            Timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
            Timer.Start();
        }
        #endregion

        #region 定时器执行的方法
        void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (BDSimObject.GlobalStatus == ESimStatus.End)
            {
                Timer.Stop();
            }
            satSpaceUCView.InvokePaint();
        }
        #endregion

        #region 图表控制逻辑
        /// <summary>
        /// 根据表格中的series建立legend列表，靠表格下方呈横排列
        /// </summary>
        /// <param name="chart"></param>
        void SetCustomLegend(Chart chart)
        {
            chart.Legends.Add(new Legend() { Enabled = false });
            chart.Legends.Add(new Legend() { LegendStyle = LegendStyle.Row, Docking = Docking.Bottom, Alignment = System.Drawing.StringAlignment.Center });
            for (int i = 0; i < chart.Series.Count; i++)
            {
                chart.Legends[1].CustomItems.Add(new LegendItem() { Enabled = true,ImageStyle = LegendImageStyle.Line, Color = chart.Series[i].Color, BorderColor = System.Drawing.Color.White, BorderWidth = 2 });
                chart.Legends[1].CustomItems[i].Tag = chart.Series[i];
                chart.Legends[1].CustomItems[i].Cells.Add(new LegendCell() { CellType = LegendCellType.Image, Image = chk_imagePath, ImageTransparentColor = System.Drawing.Color.Red });
                chart.Legends[1].CustomItems[i].Cells.Add(LegendCellType.SeriesSymbol, "", System.Drawing.ContentAlignment.MiddleCenter);
                chart.Legends[1].CustomItems[i].Cells.Add(LegendCellType.Text, chart.Series[i].Name, System.Drawing.ContentAlignment.MiddleCenter);

                //chart.Legends.Add(new Legend() { Enabled = true, Title = chart.Series[i].Name });
                //chart.Legends[0].CustomItems[i].Cells.Add(
            }
        }

        /// <summary>
        /// 表格选择区域变化时执行的事件
        /// </summary>
        /// <param name="e"></param>
        void SelectionChangedEvent(object sender, CursorEventArgs e)
        {
            if (e.Axis.AxisName == AxisName.X)
            {
                double TimeOfDay = e.Axis.ScaleView.ViewMaximum - e.Axis.ScaleView.ViewMinimum;
                //横坐标显示的时间范围在一分钟以内，坐标间隔类型设置为“秒”
                if (TimeOfDay * 86400 <= 60)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Seconds;
                }
                //横坐标显示的时间范围在一小时以内，坐标间隔类型设置为“分钟”
                else if (TimeOfDay * 24 <= 1)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Minutes;
                }
                //横坐标显示的时间范围在两天以内，坐标间隔类型设置为“小时”
                else if (TimeOfDay <= 2)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Hours;
                }
                //横坐标显示的时间范围在60以内，坐标间隔类型设置为“天”
                else if (TimeOfDay < 60)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Days;
                }
            }
        }
        
        /// <summary>
        /// 缩小表格视角大小时执行的事件
        /// </summary>
        /// <param name="e">事件参数</param>
        void AxisViewChangedEvent(object sender, ViewEventArgs e)
        {
            if (e.Axis.AxisName == AxisName.X)
            {
                double TimeOfDay = e.Axis.ScaleView.ViewMaximum - e.Axis.ScaleView.ViewMinimum;
                //横坐标显示的时间范围在一分钟以内，坐标间隔类型设置为“秒”
                if (TimeOfDay * 86400 <= 60)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Seconds;
                }
                //横坐标显示的时间范围在一小时以内，坐标间隔类型设置为“分钟”
                else if (TimeOfDay * 24 <= 1)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Minutes;
                }
                //横坐标显示的时间范围在两天以内，坐标间隔类型设置为“小时”
                else if (TimeOfDay <= 2)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Hours;
                }
                //横坐标显示的时间范围在60以内，坐标间隔类型设置为“天”
                else if (TimeOfDay < 60)
                {
                    e.ChartArea.AxisX.IntervalType = DateTimeIntervalType.Days;
                }
            }
        }

        /// <summary>
        /// 用于选择是否显示当前曲线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Chart_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            System.Windows.Forms.DataVisualization.Charting.HitTestResult result = ((Chart)sender).HitTest(e.X, e.Y);
            if (result != null && result.Object != null)
            {
                // When user hits the LegendItem
                if (result.Object is LegendItem)
                {
                    // Legend item result
                    LegendItem legendItem = (LegendItem)result.Object;

                    // series item selected
                    Series selectedSeries = (Series)legendItem.Tag;

                    if (selectedSeries != null)
                    {
                        if (selectedSeries.Enabled)
                        {
                            selectedSeries.Enabled = false;
                            if (File.Exists(unchk_imagePath))
                            {
                                legendItem.Cells[0].Image = unchk_imagePath;
                            }
                        }
                        else
                        {
                            selectedSeries.Enabled = true;
                            if (File.Exists(chk_imagePath))
                            {
                                legendItem.Cells[0].Image = chk_imagePath;
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 选择是否显示图表的网格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            if (((CheckBox)sender).IsChecked == true)
            {
                chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Transparent;
                chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Transparent;
                //chart2.ChartAreas[0].AxisY2.MajorGrid.LineColor = System.Drawing.Color.Transparent;

                chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Transparent;
                chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Transparent;
                //chart1.ChartAreas[0].AxisY2.MajorGrid.LineColor = System.Drawing.Color.Transparent;
            }
            else
            {
                chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Black;
                chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Black;
                //chart2.ChartAreas[0].AxisY2.MajorGrid.LineColor = System.Drawing.Color.Black;

                chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Black;
                chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Black;
                //chart1.ChartAreas[0].AxisY2.MajorGrid.LineColor = System.Drawing.Color.Black;
            }
        }

        ///// <summary>
        ///// 根据表格中的series建立legend列表，靠表格下方呈横排列
        ///// </summary>
        ///// <param name="chart"></param>
        void SetSimpleLegend(Chart chart)
        {
            chart.Legends.Add(new Legend() { LegendStyle = LegendStyle.Column, Docking = Docking.Bottom, Alignment = System.Drawing.StringAlignment.Center });
            for (int i = 0; i < chart.Series.Count; i++)
            {
                chart.Legends.Add(new Legend() { Enabled = true, Title = chart.Series[i].Name });
            }
        }
        #endregion

        #region 窗口关闭时释放资源
        /// <summary>
        /// 释放资源
        /// </summary>
        public void ReleaseResources()
        {
            Timer.Stop();
            IsUpdatePos = false;
        }
        #endregion

        #region  INotifyPropertyChanged 接口实现

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        #endregion

        private void cbxDopType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //chart1.Series[0].Points.Clear();
        }
    }

    /// <summary>
    /// 接收机模型，用于在启动向导时显示自定义的模型
    /// </summary>
    public class ReceiverObject
    {
        public string ModelType { get; set; }

        /// <summary>
        /// 载体名称
        /// </summary>
        public string CarrierName { get; set; }

        /// <summary>
        /// 接收机名称
        /// </summary>
        public string ReceiverName { get; set; }

        public override string ToString()
        {
            return CarrierName + "-" + ReceiverName;
        }
    }
}
